package net.atomarrow.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.PropertyPreFilter;
import com.alibaba.fastjson.serializer.SerializerFeature;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
/**
 * fastjson 工具类
 * @author Michael
 *
 */
public class JsonUtil {
    private static final SerializerFeature feature = SerializerFeature.DisableCircularReferenceDetect;

    public static String toJson(Object obj) {
        return JSON.toJSONString(obj,feature);
    }

    public static String toJsonWith(Object obj, String... param) {
        return JSON.toJSONString(obj,
                new MineSimplePropertyPreFilter(false, param), feature);
    }

    public static String toJsonWithOut(Object obj, String... param) {
        return JSON.toJSONString(obj,
                new MineSimplePropertyPreFilter(true, param), feature);
    }

    /**
     * 快捷生成一个JSONObject, 数组传入参数，偶数位是key，奇数位是value
     * @param data
     * @return
     */
    public static JSONObject createJSONObject(Serializable... data) {
        JSONObject o = new JSONObject();
        for (int i = 0; i < data.length; i++) {

            if (i % 2 != 0) continue;

            o.put(data[i].toString(), data[i+1]);
        }
        return o;
    }
}

class MineSimplePropertyPreFilter implements PropertyPreFilter {

    private final Class<?> clazz;
    private Set<String> includes = new HashSet<String>();
    private Set<String> excludes = new HashSet<String>();
    private final boolean isSkipMode;

    public MineSimplePropertyPreFilter(boolean isSkipMode, String... properties) {
        this(isSkipMode, null, properties);
    }

    public MineSimplePropertyPreFilter(boolean isSkipMode, Class<?> clazz,
                                       String... properties) {
        super();
        this.clazz = clazz;
        this.isSkipMode = isSkipMode;
        includes.add("result");
        includes.add("success");
        includes.add("msg");
        includes.add("pager");

        for (String item : properties) {
            if (item != null) {
                if (isSkipMode) {
                    this.excludes.add(item);
                } else {
                    this.includes.add(item);
                }
            }
        }
    }

    public Class<?> getClazz() {
        return clazz;
    }

    public boolean apply(JSONSerializer serializer, Object source, String name) {
        if (isSkipMode) {
            if (includes.contains(name)) {
                return true;
            }
            return !excludes.contains(name);
        } else {
            return includes.contains(name);
        }
    }

    public Set<String> getIncludes() {
        return includes;
    }

    public Set<String> getExcludes() {
        return excludes;
    }

    public void setIncludes(Set<String> includes) {
        this.includes = includes;
    }

    public void setExcludes(Set<String> excludes) {
        this.excludes = excludes;
    }

}
